package com.sinodata.bsm.center.service.event;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sinodata.bsm.center.bean.Condition;
import com.sinodata.bsm.center.bean.EventCorrelationPolicyBean;
import com.sinodata.bsm.center.bean.Page;
import com.sinodata.bsm.center.bean.TreeData;
import com.sinodata.bsm.center.cache.EventCorrelationLinkCache;
import com.sinodata.bsm.center.cache.EventCorrelationPolicyCache;
import com.sinodata.bsm.center.cache.EventTypeCache;
import com.sinodata.bsm.center.cache.ResTypeCache;
import com.sinodata.bsm.center.dao.BaseDao;
import com.sinodata.bsm.center.dao.impl.EventCorrelationDaoImpl;
import com.sinodata.bsm.common.constants.EventCorrelationConstants;
import com.sinodata.bsm.common.vo.EventCorrelationLink;
import com.sinodata.bsm.common.vo.EventCorrelationPolicy;
import com.sinodata.bsm.common.vo.EventType;
import com.sinodata.bsm.common.vo.ResType;

/**
 * <p>
 * Description: 
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-6-13 PM 5:00:52     liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
@Service
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class EventCorrelationPolicyService {

    @Autowired
    private BaseDao baseDao;

    @Autowired
    private EventCorrelationDaoImpl eventCorrelationDao;

    @Autowired
    private ResTypeCache resTypeCache;

    @Autowired
    private EventTypeCache eventTypeCache;

    @Autowired
    private EventCorrelationPolicyCache eventCorrelationPolicyCache;

    @Autowired
    private EventCorrelationLinkCache eventCorrelationLinkCache;

    @Transactional(propagation = Propagation.REQUIRED)
    public Long add(EventCorrelationPolicy eventCorrelationPolicy, List<EventCorrelationLink> list) {
        baseDao.save(eventCorrelationPolicy);
        Long id = eventCorrelationPolicy.getId();
        for (EventCorrelationLink e : list) {
            e.setEventCorrelationPolicyId(id);
            baseDao.save(e);
        }
        return id;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Long update(EventCorrelationPolicy eventCorrelationPolicy, List<EventCorrelationLink> list) {
        baseDao.saveOrUpdate(eventCorrelationPolicy);
        Long id = eventCorrelationPolicy.getId();
        //先删除和主事件关联的从事件
        for (EventCorrelationLink e : eventCorrelationLinkCache.getAll()) {
            if (e.getEventCorrelationPolicyId().equals(id)) {
                baseDao.delete(e);
            }
        }
        //再新增从事件
        for (EventCorrelationLink e : list) {
            e.setEventCorrelationPolicyId(id);
            baseDao.save(e);
        }
        return id;
    }

    public EventCorrelationPolicy get(Long id) {
        return eventCorrelationPolicyCache.get(id);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public List<EventCorrelationLink> delete(Long id) {
        EventCorrelationPolicy eventCorrelationPolicy = eventCorrelationPolicyCache.get(id);
        //删除主事件
        baseDao.delete(eventCorrelationPolicy);
        //删除从事件
        List<EventCorrelationLink> listEventCorrelationLink = eventCorrelationLinkCache.getAll();
        for (EventCorrelationLink eventCorrelationLink : listEventCorrelationLink) {
            if (eventCorrelationLink.getEventCorrelationPolicyId().equals(id)) {
                baseDao.delete(eventCorrelationLink);
            }
        }
        return listEventCorrelationLink;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public EventCorrelationPolicy changeStatus(Long id) {
        EventCorrelationPolicy eventCorrelationPolicy = eventCorrelationPolicyCache.get(id);
        if (eventCorrelationPolicy.getStatus().equals("0")) {
            eventCorrelationPolicy.setStatus("1");
        } else {
            eventCorrelationPolicy.setStatus("0");
        }
        baseDao.update(eventCorrelationPolicy);
        return eventCorrelationPolicy;
    }

    /**
     * 获取活动的事件关联策略
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<EventCorrelationPolicy> getActiveEventCorrelationPolicys() {
        String hql = "from EventCorrelationPolicy where status = " + EventCorrelationConstants.STATUS_START;
        return (List<EventCorrelationPolicy>) baseDao.findListByHql(hql);
    }

    public void batchDelete() {

    }

    public void batchStart() {

    }

    public Page<EventCorrelationPolicyBean> findByPage(Page<EventCorrelationPolicyBean> page, Condition condition) {
        return eventCorrelationDao.findEventCorrelationPolicyByPage(page, condition);
    }

    public List<TreeData> getResTypeTreeData() {
        List<TreeData> listResult = new ArrayList<TreeData>();
        //自定义事件类别
        TreeData treeDataCustom = new TreeData();
        treeDataCustom.setId("id");
        treeDataCustom.setName("自定义事件类别");
        treeDataCustom.setIconSkin("type1");
        List<TreeData> childrenCustom = new ArrayList<TreeData>();
        for (EventType eventType : eventTypeCache.getAllCustom()) {
            TreeData treeDataCustom1 = new TreeData();
            treeDataCustom1.setId("event" + eventType.getId());
            treeDataCustom1.setName(eventType.getName());
            treeDataCustom1.setIconSkin("eventtype");
            childrenCustom.add(treeDataCustom1);
        }
        treeDataCustom.setChildren(childrenCustom);
        listResult.add(treeDataCustom);

        //非自定义
        List<ResType> listAll = resTypeCache.getAll();
        Collections.sort(listAll);
        List<ResType> list = new ArrayList<ResType>();
        for (ResType resType : listAll) {
            if (resType.getParentId() == null) {
                TreeData treeData = new TreeData();
                treeData.setId(String.valueOf(resType.getId()));
                treeData.setName(resType.getName());
                treeData.setIconSkin("type0");
                List<EventType> listEventType = eventTypeCache.findByResTypeId(resType.getId());
                if (listEventType.size() != 0) {
                    List<TreeData> children = new ArrayList<TreeData>();
                    TreeData treeData1 = new TreeData();
                    treeData1.setId("id");
                    treeData1.setName("事件类别");
                    treeData1.setIconSkin("type1");
                    List<TreeData> eventTypeList = new ArrayList<TreeData>();
                    for (EventType eventType : listEventType) {
                        TreeData treeData2 = new TreeData();
                        treeData2.setId("event" + String.valueOf(eventType.getId()));
                        treeData2.setName(eventType.getName());
                        treeData2.setIconSkin("eventtype");
                        eventTypeList.add(treeData2);
                    }
                    treeData1.setChildren(eventTypeList);
                    children.add(treeData1);
                    treeData.setChildren(children);
                }
                listResult.add(treeData);
            } else {
                list.add(resType);
            }
        }
        //循环遍历其下子节点
        getResTypeTreeDataCycle(list, listResult);
        return listResult;
    }

    private void getResTypeTreeDataCycle(List<ResType> listScope, List<TreeData> listResult) {
        for (TreeData treeData : listResult) {
            List<TreeData> children = new ArrayList<TreeData>();
            List<ResType> list = new ArrayList<ResType>();
            for (ResType resType : listScope) {
                if (String.valueOf(resType.getParentId()).equals(treeData.getId())) {
                    TreeData treeData1 = new TreeData();
                    treeData1.setId(String.valueOf(resType.getId()));
                    treeData1.setName(resType.getName());
                    treeData1.setIconSkin("type0");
                    List<EventType> listEventType = eventTypeCache.findByResTypeId(resType.getId());
                    if (listEventType.size() != 0) {
                        List<TreeData> children1 = new ArrayList<TreeData>();
                        TreeData treeData3 = new TreeData();
                        treeData3.setId("id");
                        treeData3.setName("事件类别");
                        treeData3.setIconSkin("type1");
                        List<TreeData> eventTypeList = new ArrayList<TreeData>();
                        for (EventType eventType : listEventType) {
                            TreeData treeData2 = new TreeData();
                            treeData2.setId("event" + String.valueOf(eventType.getId()));
                            treeData2.setName(eventType.getName());
                            treeData2.setIconSkin("eventtype");
                            eventTypeList.add(treeData2);
                        }
                        treeData3.setChildren(eventTypeList);
                        children1.add(treeData3);
                        treeData1.setChildren(children1);
                    }
                    children.add(treeData1);
                } else {
                    list.add(resType);
                }
            }
            if (children.size() != 0) {
                getResTypeTreeDataCycle(list, children);
                List<TreeData> listChildren = treeData.getChildren();
                if (listChildren != null) {
                    listChildren.addAll(children);
                } else {
                    listChildren = children;
                }
                treeData.setChildren(listChildren);
            }
        }
    }

    public boolean checkName(String name) {
        if (eventCorrelationDao.getByName(name) > 0) {
            return false;
        } else {
            return true;
        }
    }
}
